package com.tj.view.view;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

import static android.content.ContentValues.TAG;

/**
 * Created by Administrator on 2017/1/16 0016.
 *
 * 流式布局，作用：标签，关键词等
 *
 */

public class FlowLayout extends ViewGroup {

    /**
     * 代码中单独new该控件时调用
     * @param context
     */
    public FlowLayout(Context context) {
        this(context, null);
    }

    /**
     * 在布局文件XML的控件的调用,有自定义属性时调用
     * @param context
     * @param attrs
     */
    public FlowLayout(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    /**
     * 该方法系统不会调用,只有自己代码调用，例如上面的this(context, attrs, 0)
     * @param context
     * @param attrs
     * @param defStyleAttr
     */
    public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
        int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
        int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
        int modeHeight = MeasureSpec.getMode(heightMeasureSpec);

        //如果布局flowlayout中是warp_content时，需要计算
        int width=0;
        int height=0;

        //记录flowlayout每一行的宽度和高度
        int lineWidth=0;
        int lineHeight=0;

        //得到子view的个数
        int cCount = getChildCount();
        for(int i=0;i<cCount;i++){

            View child = getChildAt(i);
            //测量子view的宽和高
            measureChild(child,widthMeasureSpec,heightMeasureSpec);
            //得到LayoutParams
            MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
            //子view占据的宽度
            int childWidth = child.getMeasuredWidth()+lp.leftMargin+lp.rightMargin;
            //子view占据的高度
            int childHeight = child.getMeasuredHeight()+lp.topMargin+lp.bottomMargin;

            //如果当前行宽度+下个子宽度大于父容器的最大宽度, 需要换行
            if(lineWidth + childWidth > sizeWidth){

                //比较当前的宽度，取最大值
                width = Math.max(width,lineWidth);
                //此时换行了，重置linewidth
                lineWidth = childWidth;
                //叠加当前高度
                height += lineHeight;
                //开启新一行的高度
                lineHeight = childHeight;
            } else {
                lineWidth += childWidth;
                lineHeight = Math.max(lineHeight, childHeight);
            }

            //最后一个，则将记录最大宽度和当前height做比较
            if(i == cCount - 1){
                width = Math.max(width, lineWidth);
                height += lineHeight;
            }
        }

        /**
         * 会测量多次，所以log里打印多次，且以最后一次为准
         */
        Log.e(TAG, "onMeasure:sizeWidth= "+sizeWidth);
        Log.e(TAG, "onMeasure:sizeHeight= "+sizeHeight);

        setMeasuredDimension(
                 (modeWidth == MeasureSpec.EXACTLY ? sizeWidth:width)
                ,(modeHeight == MeasureSpec.EXACTLY ? sizeHeight:height));
    }

    /**
     * 存储所有的view
     */
    private List<List<View>> mAllView = new ArrayList<>();

    /**
     * 每一行的高度
     */
    private List<Integer> mLineHeightList = new ArrayList<>();

    @Override
    protected void onLayout(boolean b, int i, int i1, int i2, int i3) {


        mAllView.clear();
        mLineHeightList.clear();
        //当前自定义viewGroup的宽度
        int width = getWidth();

        int lineWidth =0;
        int lineHeight =0;

        //每一行的view集合
        List<View> lineViews = new ArrayList<>();

        /**
         * 获取所有的子view
         */
        int cCount = getChildCount();
        for(int j=0;j<cCount;j++){

            View child = getChildAt(j);
            MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();

            int childWidth = child.getMeasuredWidth();
            int childHeight = child.getMeasuredHeight();

            //换行
            if(childWidth + lineWidth + lp.leftMargin + lp.rightMargin > width){

                //记录每一行的高度
                mLineHeightList.add(lineHeight);

                mAllView.add(lineViews);

                //重置
                lineWidth =0;
                lineHeight = childHeight + lp.topMargin + lp.bottomMargin;

                //重置每一行view的集合
                lineViews = new ArrayList<>();
            }

            lineWidth += childWidth + lp.leftMargin+lp.rightMargin;
            lineHeight = Math.max(lineHeight,childHeight+lp.topMargin+lp.bottomMargin);
            //每一行view的集合添加
            lineViews.add(child);
        }

        //处理最后一行
        mLineHeightList.add(lineHeight);
        mAllView.add(lineViews);

        /**
         * 下面设置每个子view的位置
         */
        int left =0;
        int top =0;
        //行数
        int lineNum = mAllView.size();
        for (int k=0; k<lineNum; k++){

            //当前行的所有view
            lineViews = mAllView.get(k);
            //当前行高度
            lineHeight = mLineHeightList.get(k);

            //计算当前行的所有view位置
            for(int j=0;j<lineViews.size();j++){

                View child = lineViews.get(j);

                //判断child的状态
                if(child.getVisibility() == View.GONE){
                    continue;
                }

                MarginLayoutParams lp = (MarginLayoutParams)child.getLayoutParams();

                //lc是left child的缩写
                int lc = left + lp.leftMargin;
                int tc = top + lp.topMargin;
                int rc = lc + child.getMeasuredWidth();
                int bc = tc + child.getMeasuredHeight();

                child.layout(lc,tc,rc,bc);

                left += child.getMeasuredWidth() +lp.leftMargin+lp.rightMargin;
            }

            //行于行之间,left清空，top累加
            left =0;
            top += lineHeight;
        }
    }

    /**
     * 生成当前ViewGroup中调用子view对应的LayoutParams
     * @param attrs
     * @return
     */
    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MarginLayoutParams(getContext(),attrs);
    }


}
;